package websocket.controller;

import gnu.io.SerialPort;
import org.apache.catalina.core.ApplicationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import websocket.dto.ResultDTO;
import websocket.dto.ResultEnum;
import websocket.entity.vo.SerialPortVo;
import websocket.enum_.MsgType;
import websocket.exception_.*;
import websocket.listener.MyListener;
import websocket.socket_.SocketMsg;
import websocket.socket_.WebSocketServer;
import websocket.util.*;

import java.io.IOException;
import java.util.ArrayList;

import static websocket.controller.ConnectionManageController.portMap;

/**
 * @ClassName SerialController
 * @Des TODO 无人机开启串口监听
 * @Author lg
 * @Date 2022/7/8 17:26
 * @Version 1.0.0
 **/
@RestController
@RequestMapping("/api/serial/openPort")
public class SerialController {

    private static final Logger log = LoggerFactory.getLogger(SerialController.class);
    //航向信息串口号
    @Value("${chaunKou.hangXiangPort}")
    private String hangXiangPort;
    //航向/最佳位置名称
    @Value("${chaunKou.hangXiangName}")
    private String hangXiangName;
    //水平仪串口号
    @Value("${chaunKou.horizontalPort}")
    private String horizontalPort;
    //水平仪名称
    @Value("${chaunKou.horizontalName}")
    private String horizontalName;
    //双轴转台串口号
    @Value("${chaunKou.shuangZhouZhuanTaiPort}")
    private String shuangZhouZhuanTaiPort;
    //双轴转台
    @Value("${chaunKou.shuangZhouZhuanTaiName}")
    private String shuangZhouZhuanTaiName;
    //无人机闭合通路串口号
    @Value("${chaunKou.wuRenJiPort}")
    private String wuRenJiPort;
    //无人机闭合通路名称
    @Value("${chaunKou.wuRenJiName}")
    private String wuRenJiName;
    //波特率
    @Value("${chaunKou.boTeLv}")
    private Integer boTeLv;

    @GetMapping(value = "/aaa")
    public ResultDTO openPort111() {

        try {
            SerialPortVo serialPortVo = SerialTool.openPort(shuangZhouZhuanTaiName, shuangZhouZhuanTaiPort, 115200);

            // 指令：通讯串口消息使用
            String sendChuanKouData1 = "AA A5 55 0F 00 00 00 00 00 00 00 00 00 B3";
            serialPortVo.sendData(DigitalTrans.hex2byte(DigitalTrans.convertHexToStringAndTrim(sendChuanKouData1)));
            // 指令：外环使能（意思为锁定外环，抱死状态）
            String sendChuanKouData2 = "AA A5 55 2E 00 00 00 00 00 00 00 00 00 D2";
            serialPortVo.sendData(DigitalTrans.hex2byte(DigitalTrans.convertHexToStringAndTrim(sendChuanKouData2)));
            // 指令：外环运行（参数为测试数据）
            String sendChuanKouData3 = "AA A5 55 21 F0 D8 FF FF A0 30 75 00 00 D0";
            serialPortVo.sendData(DigitalTrans.hex2byte(DigitalTrans.convertHexToStringAndTrim(sendChuanKouData3)));
            // 指令：外环使能取消
            String sendChuanKouData4 = "AA A5 55 2E 00 00 00 00 80 00 00 00 00 52";
            serialPortVo.sendData(DigitalTrans.hex2byte(DigitalTrans.convertHexToStringAndTrim(sendChuanKouData4)));
            SerialPortVo.sendDataToComPort(serialPortVo.getSerialPort(), DigitalTrans.hex2byte(DigitalTrans.convertHexToStringAndTrim(sendChuanKouData4)));
            // 绑定监听
            serialPortVo.bindListener(new MyListener(), 500);
            SerialPortVo com4 = ComBeanUtil.getMap("COM4");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @GetMapping
    public ResultDTO openPort() {
        try {
            ArrayList<String> ports = SerialTool.findPort();
            if (CollectionUtils.isEmpty(ports)) {
                log.info("<----------【未发现串口,请检查串口设备是否连接成功】-------------->" + ports);
                return ResultDTO.fail(ResultEnum.NOT_FIND_CHUAN_KOU_DATA);
            }
            log.info("<----------【发现串口】-------------->" + ports);
//            hangXiangPort=portMap.get("hxPort");
            if (ports.contains(hangXiangPort)) {
                log.info("【航向】打开串口：" + hangXiangPort);
                log.info("【发送指令】：unlog all");
                log.info("【发送指令】：log headinga ontime 1");
                log.info("【发送指令】：SAVECONFIG");
                SerialPortVo serialPortVo = SerialTool.openPort(hangXiangName, hangXiangPort, boTeLv);
                String sendChuanKouData0 = "unlogall";
                serialPortVo.sendData(sendChuanKouData0.getBytes());
                String sendChuanKouData1 = "log headingb ontime 1";
                serialPortVo.sendData(sendChuanKouData1.getBytes());
                String sendChuanKouData2 = "SAVECONFIG";
                serialPortVo.sendData(sendChuanKouData2.getBytes());
                serialPortVo.bindListener(new MyListener(), 500);
            } else {
                log.info("未发现【航向串口】" + hangXiangPort);
            }
//            horizontalPort=portMap.get("cldPort");
            if (ports.contains(horizontalPort)) {
                log.info("【水平仪】打开串口：" + horizontalPort);
                log.info("【发送指令】：unlog all");
                log.info("【发送指令】：log bestposb ontime 1");
                log.info("【发送指令】：SAVECONFIG");
                SerialPortVo shuiPingYiVO = SerialTool.openPort(horizontalName, horizontalPort, boTeLv);
                String sendZhiLing0 = "unlogall";
                shuiPingYiVO.sendData(sendZhiLing0.getBytes());
                String sendZhiLing1 = "log bestposb ontime 1";
                shuiPingYiVO.sendData(sendZhiLing1.getBytes());
                String sendZhiLing2 = "SAVECONFIG";
                shuiPingYiVO.sendData(sendZhiLing2.getBytes());
                shuiPingYiVO.bindListener(new MyListener(), 500);
            } else {
                log.info("未发现【水平仪串口】" + horizontalPort);
            }
//            wuRenJiPort=portMap.get("wrjPort");
            if (ports.contains(wuRenJiPort)) {
                log.info("【无人机闭合通路】打开串口：" + wuRenJiPort);
                log.info("【发送指令】：unlogall");
                log.info("【发送指令】：log bestposb ontime 1");
                log.info("【发送指令】：SAVECONFIG");
                SerialPortVo shuiPingYiVO = SerialTool.openPort(wuRenJiName, wuRenJiPort, boTeLv);
                String sendZhiLing0 = "unlog all";
                shuiPingYiVO.sendData(sendZhiLing0.getBytes());
                String sendZhiLing1 = "log bestposb ontime 1";
                shuiPingYiVO.sendData(sendZhiLing1.getBytes());
                String sendZhiLing2 = "SAVECONFIG";
                shuiPingYiVO.sendData(sendZhiLing2.getBytes());
                shuiPingYiVO.bindListener(new MyListener(), 500);
            } else {
                log.info("未发现【无人机闭合通路串口】" + wuRenJiPort);
            }

        } catch (SendDataToSerialPortFailure sendDataToSerialPortFailure) {
            sendDataToSerialPortFailure.printStackTrace();
            return ResultDTO.externalError(503, "没有中找到无人机转台");
        } catch (SerialPortOutputStreamCloseFailure serialPortOutputStreamCloseFailure) {
            serialPortOutputStreamCloseFailure.printStackTrace();
            return ResultDTO.externalError(503, "没有中找到无人机转台");
        } catch (PortInUse portInUse) {
            portInUse.printStackTrace();
        } catch (NoSuchPort noSuchPort) {
            noSuchPort.printStackTrace();
            return ResultDTO.externalError(503, "没有中找到无人机转台！");
        } catch (NotASerialPort notASerialPort) {
            notASerialPort.printStackTrace();
            return ResultDTO.externalError(503, "没有中找到无人机转台！");
        } catch (SerialPortParameterFailure serialPortParameterFailure) {
            serialPortParameterFailure.printStackTrace();
            return ResultDTO.externalError(503, "从转台读取数据时出错！");
        } catch (TooManyListeners tooManyListeners) {
            tooManyListeners.printStackTrace();
            return ResultDTO.externalError(503, "监听数量过多！添加操作失败！");
        }
        return ResultDTO.success(null);
    }

    @GetMapping("/test")
    public ResultDTO test() {
        try {
            System.out.println("---------------test---------");
            String str = "{\"msg\":\"{\\\"appId\\\":-65536,\\\"data\\\":{\\\"mountInfo\\\":[],\\\"openid\\\":\\\"\\\",\\\"uavInfo\\\":{\\\"airSpeed\\\":0,\\\"altitude\\\":0,\\\"battaryRemain\\\":92,\\\"climbRate\\\":-8.246846264228225E-4,\\\"current\\\":0,\\\"currentMountType\\\":[],\\\"customData\\\":{\\\"controlStatus\\\":1,\\\"joystickConnectionStatus\\\":0,\\\"positionStatus\\\":1,\\\"returnAltitude\\\":0,\\\"returnSpeed\\\":0,\\\"returnVoltage\\\":0,\\\"signalStatus\\\":1,\\\"transportStatus\\\":1},\\\"dateTime\\\":1657615282219,\\\"distanceToHome\\\":0,\\\"distanceToNext\\\":0,\\\"flightMode\\\":\\\"手动模式\\\",\\\"flightSortie\\\":\\\"\\\",\\\"flightState\\\":0,\\\"flightTime\\\":\\\"0.00\\\",\\\"groundSpeed\\\":0.002912126947194338,\\\"height\\\":2.5062925815582275,\\\"isLocation\\\":\\\"0\\\",\\\"latitude\\\":\\\"nan\\\",\\\"longitude\\\":\\\"nan\\\",\\\"pitch\\\":-0.6146602493536718,\\\"platformType\\\":0,\\\"push_status\\\":\\\"0\\\",\\\"roll\\\":2.390295136371778,\\\"satCount\\\":0,\\\"taskId\\\":\\\"\\\",\\\"uid\\\":1107296280,\\\"unmannedId\\\":1,\\\"voltage\\\":51.335,\\\"yaw\\\":180},\\\"videoInfo\\\":[{\\\"vUrl\\\":\\\"\\\",\\\"videoType\\\":\\\"rtmp\\\"},{\\\"vUrl\\\":\\\"\\\",\\\"videoType\\\":\\\"hls\\\"},{\\\"vUrl\\\":\\\"\\\",\\\"videoType\\\":\\\"flv\\\"}]},\\\"deviceHardId\\\":\\\"\\\",\\\"deviceType\\\":\\\"1\\\",\\\"systemCode\\\":\\\"1\\\"}\",\"msgType\":\"INFO\"}";
            SocketMsg socketMsg = new SocketMsg(str, MsgType.INFO);
            WebSocketServer.sendInfo(socketMsg, "nrj");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResultDTO.success(null);
    }
}
